home *** CD-ROM | disk | FTP | other *** search
- page 58,132
- ; file: LERP.ASM
- ;
- ; LERP stands for Linear intERPolation.
- ; THIS ROUTINE ACCEPTS THREE SHORT INTEGET ARGUMENTS, IT
- ; MULTIPLYS THE FIRST TWO TOGETHER, THEN ADDS HALF OF THE
- ; THIRD ARGUMENT AND DIVIDES BY THE THIRD ARGUMENT.
- ;
- ; THE MULTIPLY IS A 16*16 GIVING 32 BITS, AND THE DIVIDE IS
- ; A 32/16 GIVING 16 BIT DIVIDE, SO NO OVERFLOW SHOULD HAPPEN.
- ; ADDING HALF OF THE DIVISOR RESULTS IN THE ANSWER BEING ROUNDED
- ; OFF AT 0.5. DIVIDING BY ZERO WILL RESULT IN AN ANSWER THAT IS
- ; +/- 32767 -- THE 16BIT INTEGER EQUIVALENT OF INFINITY.
- ;
- ; (c) Copyright 1984 by The Computer Entomologist
- ;
- ; Permission is hearby granted to use or distribute this software
- ;without any restrictions. You may make copies for yourself or your
- ;friends. You may include it in any hardware or software product that you
- ;sell for profit.
- ;
- ; This software is distributed as is, and is not guaranteed to work
- ;on any particular hardware/software configuration. Furthermore, no
- ;liability is granted with this software: the user takes responcibility for
- ;any damage this software may do to his system.
- ;
- ; Nasy notices aside, if you have any questions about this software, you
- ;can reach me at the address below. If you impliment any new features or
- ;find (and fix!) any bugs, I would be happy to hear from you.
- ;
- ; Mike Higgins
- ; The Computer Entomologist
- ; P.O. Box 197
- ; Duncans Mills, CA 95430
- ;
- ;PARAMETERS:
- NUM=6 ;A NUMBER TO BE TRANSFORMED
- MULT=8 ;THE AMOUNT TO MULTIPLY BY
- DIVIS=10 ;THE AMOUNT TO DIVIDE BY
-
- INCLUDE MODEL.H
- INCLUDE PROLOGUE.H
-
- PUBLIC LERP
- LERP PROC FAR
- PUSH BP ;DO THE NORMAL STACK FRAMING
- MOV BP,SP
-
- MOV AX,NUM[BP] ;GET THE FIRST ARGUMENT
- XOR BH,BH ;BH WILL CONTAIN THE SIGN OF RESULT
- OR AH,AH ;TAKE THE ABS OF 1ST ARGUMENT
- JGE POS1
- MOV BH,AH ;SAVE THE SIGN IN BH
- NEG AX
- POS1:
- MOV CX,MULT[BP] ;GET THE 2ND ARGUMENT
- OR CH,CH ;TAKE IT'S ABSULUTE VALUE
- JGE POS2
- XOR BH,CH ;BUT SAVE SIGN FIRST
- NEG CX
- POS2:
- IMUL CX ;MULTIPLY BY THE 2ND ARGUMENT.
- MOV CX,DIVIS[BP] ;GET THE THIRD ARGUMENT,
- OR CX,CX ;CHECK IT TO SEE IF IT IS
- JG POS3 ;POSITIVE, OR IF
- JL NEG3 ;NEGATIVE.
- INFINITY:
- MOV AX,07FFFH ;IF ZERO, RETURN A LARGE NUMBER
- JMP SIGN ;POSITIVE OR NEGATIVE INFINITY)
- NEG3:
- XOR BH,CH ;SAVE THE SIGN OF DIVISOR,
- NEG CX ;AND MAKE IT POSITIVE
- POS3:
- IDIV CX ;FINALLY, DO THE DIVISION
- SAR CX,1 ;AND DIVIDE DIVISOR BY 2
- CMP CX,DX ;IS REMAINDER >= 1/2 DIVISOR?
- JG SIGN ;NO.
- INC AX ;YES, INCRIMENT RESULT.
- SIGN: OR BH,BH ;CHECK THE SIGN OF THE RESULT
- JGE DONE ;IF POSITIVE, YOU CAN QUIT
- NEG AX ;ELSE MAKE THE RESULT NEGATIVE NOW
- DONE:
- POP BP
- RET
- LERP ENDP
-
- ;
- ; Can you beleive it? On the 8088/86/286 it is impossible
- ; to test for integer overflow on a divide! The only way to detect
- ; this error is to catch divide-by-zero interupts! So I wrote the
- ; following two routines: OVRSET() must be called once by your main
- ; program, and it points the divide overflow vector at DIVOVR. This
- ; version of DIVOVR always assumes a 32 by 16 bit divide, and just
- ; loads AX and DX with "infinity" with no remainder.
- ;
- DIVOVR PROC FAR ;ROUTINE TO PROCESS DIVISION OVERFLOW ERRORS
- MOV AX,07FFFH ;CHANGE AX TO A LARGE NUMBER
- XOR DX,DX ;ZERO DX (ASSUME 16 BIT DIVIDE)
- IRET ;AND RETURN, THAT'S ALL.
- DIVOVR ENDP
-
- PUBLIC OVRSET
- OVRSET PROC FAR ;ROUTINE TO SET DIVISION OVERFLOW INTERUPT VECTOR
-
- PUSH DS
- MOV AX,CS ;USE CURRENT CODE SEGMENT
- MOV DS,AX
- MOV DX,OFFSET @CODE:DIVOVR
- MOV AX,02500H ;ASK TO LOAD THE DIVIDE BY ZERO VECTOR
- INT 21H
- POP DS
- RET
- OVRSET ENDP
-
- INCLUDE EPILOGUE.H
-
- END